package org.com.sec.critical;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Provides several hash fuctions.
 *
 * @author See <a href="the Google Code page of the easy-utils
 * library">http://code.google.com/p/easy-utils/</a> for collaborators and other
 * information.
 */
public abstract class HashGenerators {

    /**
     * Applies NSA SHA-512 to a given text. ISO-8859-1 is used as charset.
     *
     * @param string {@link String} The target string.
     * @return {@link String} The SHA-512 digest.
     */
    public static String sha512(String string) {
        return HashGenerators.sha512(string.getBytes(Charset.forName("ISO-8859-1")));
    }

    /**
     * Applies NSA SHA-512 to a given text.
     *
     * @param string {@link String} The target string.
     * @param charset {@link Charset} The charset to use when decoding the
     * target string.
     * @return {@link String} The SHA-512 digest.
     */
    public static String sha512(String string, Charset charset) {
        return HashGenerators.sha512(string.getBytes(charset));
    }

    /**
     * Applies NSA SHA-512 to a given set of data.
     *
     * @param bytes Array of bytes with the data to generate the hash from.
     * @return {@link String} The SHA-512 digest.
     */
    public static String sha512(byte[] bytes) {
        return HashGenerators.hashForName(bytes, "SHA-512");
    }

    /**
     * Applies NSA SHA-1 to a given text. ISO-8859-1 is used as charset.
     *
     * @param string {@link String} The target string.
     * @return {@link String} The SHA-1 digest.
     */
    public static String sha1(String string) {
        return HashGenerators.sha1(string.getBytes(Charset.forName("ISO-8859-1")));
    }

    /**
     * Applies NSA SHA-1 to a given text.
     *
     * @param string {@link String} The target string.
     * @param charset {@link Charset} The charset to use when decoding the
     * target string.
     * @return {@link String} The SHA-1 digest.
     */
    public static String sha1(String string, Charset charset) {
        return HashGenerators.sha512(string.getBytes(charset));
    }

    /**
     * Applies NSA SHA-512 to a given set of data.
     *
     * @param bytes Array of bytes with the data to generate the hash from.
     * @return {@link String} The SHA-1 digest.
     */
    public static String sha1(byte[] bytes) {
        return HashGenerators.hashForName(bytes, "SHA-1");
    }

    /**
     * Applies a chosen hash to a given set of data.
     *
     * @param bytes Array of bytes with the data to generate the hash from.
     * @param hashName {@link String} The name of the hash function.
     * @return {@link String} The SHA-1 digest.
     */
    public static String hashForName(byte[] bytes, String hashName) {
        MessageDigest messageDigest = null;

        try {
            messageDigest = MessageDigest.getInstance(hashName);
        } catch (NoSuchAlgorithmException ex) {
            System.err.println(hashName + " algorithm couldn't be found in the system - " + ex.getMessage());
        }
        messageDigest.reset();

        byte[] result = messageDigest.digest(bytes);

        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < result.length; i++) {
            if (result[i] <= 15 && result[i] >= 0) {
                hexString.append("0");
            }
            hexString.append(Integer.toHexString(255 & result[i]));
        }

        return hexString.toString();
    }
}
